package com.godliu.file.demo.controller;

import com.godliu.file.demo.pojo.BaseFile;
import com.godliu.file.demo.pojo.FileError;
import com.godliu.file.demo.pojo.FilePreview;
import com.godliu.file.demo.pojo.FilePreviewConfig;
import com.godliu.file.demo.utils.DateUtils;
import com.godliu.file.demo.utils.ImgUtils;
import com.godliu.file.demo.utils.StringCheck;
import com.godliu.file.demo.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping(value = "/file")
public class FileServices {

    @Value("${BaseFilePath}")
    String baseFilePath;
    @Value("${PicFileSuffix}")
    String PicFileSuffix;
    @Value("${VideoFileSuffix}")
    String VideoFileSuffix;
    @Value("${OfficeSuffix}")
    String OfficeSuffix;
    @Value("${AudioSuffix}")
    String AudioSuffix;
    @Value("${MediaBaseUrl}")
    String MediaBaseUrl;
    //默认处理文件上传的编码
    private String FILE_UPLOAD_ENCODING = "UTF-8";

    /**
     * 附件上传---bootstrap-inputfile
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/uploadFileWeb", method = RequestMethod.POST)
    public Object uploadFileWeb(HttpServletRequest request, @RequestParam MultipartFile file, HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        log.info("uploadFileWeb...");

        BaseFile bf = upload(request, file);

        if (bf == null) {
            FileError fe = new FileError();
            fe.setError("上传失败，可能是文件格式不匹配");
            return fe;
        }
        log.info("complete uploadFileWeb : " + bf.getNewPath());
        return bf;
    }

    /**
     * 附件上传
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public Object uploadFile(HttpServletRequest request, @RequestParam MultipartFile file) {
        log.info("upload file...");

        BaseFile bf = upload(request, file);
        if (bf == null) {
            FileError fe = new FileError();
            fe.setError("上传失败，可能是文件格式不匹配");
            return fe;
        }

        log.info("complete upload file : " + bf.getNewPath());
        return bf;
    }

    /**
     * 多附件上传
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/uploadFiles", method = RequestMethod.POST)
    public Object uploadFiles(HttpServletRequest request, @RequestParam("file") MultipartFile[] files) {
        log.info("upload files...");

        List<BaseFile> bfs = new ArrayList<BaseFile>();

        if (files != null && files.length > 0) {
            for (MultipartFile file : files) {
                BaseFile bf = upload(request, file);
                if (bf != null) bfs.add(bf);
            }
        }

        log.info("complete upload files : " + bfs.size());
        return bfs;
    }

    /**
     * 内部上传附件方法
     *
     * @param request
     * @param file
     * @return
     */
    private BaseFile upload(HttpServletRequest request, MultipartFile file) {
        BaseFile bf = new BaseFile();

        //附件默认保存路径-中间部分
        String midpath = getMidpath(request);
        //附件默认保存路径-时间部分
        String datepath = getDatepath(request);
        //限制图片大小，如果超出限制，则压缩，单位是K
        String maxpicm = getMaxpicm(request);
        //限制图片宽度，如果超出则等比例缩小
        String maxpicwidth = getMaxpicwidth(request);
        //限制图片高度，如果超出则等比例缩小
        String maxpicheight = getMaxpicheight(request);
        try {
            request.setCharacterEncoding(FILE_UPLOAD_ENCODING);

            String fileName = file.getOriginalFilename();
            String fileextension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();

            String sysDefineSuffix = PicFileSuffix + "," + VideoFileSuffix + "," + OfficeSuffix + "," + AudioSuffix;

            //后缀名不允许
            if (sysDefineSuffix.indexOf(fileextension) == -1) {
                FileError fe = new FileError();
                fe.setError("只允许如下后缀：" + sysDefineSuffix);
                return null;
            }

            //确定根目录
            String basepath = "/upload";
            if (PicFileSuffix.contains(fileextension)) {
                basepath += "/pics";
                bf.setType("image");
            } else if (VideoFileSuffix.contains(fileextension)) {
                basepath += "/videos";
                bf.setType("video");
            } else if (OfficeSuffix.contains(fileextension)) {
                basepath += "/documents";
                bf.setType("document");
            } else if (AudioSuffix.contains(fileextension)) {
                basepath += "/audios";
                bf.setType("audio");
            } else {
                basepath += "/others";
                bf.setType("other");
            }

            //完整目录
            String fullPath = baseFilePath + basepath + midpath + datepath;

            //创建完整目录
            File filepath = new File(fullPath);
            if (!filepath.exists()) {
                filepath.mkdirs();
            }

            //附件名
            String realfilename = DateUtils.getDateTimeRandomId() + fileextension;

            //完整附件名
            String fullFileName = fullPath + "/" + realfilename;

            //写入附件
            File realfile = new File(fullFileName);
            if (file.getSize() != 0) {
                file.transferTo(realfile);
            }
            file = null;


            bf.setLengthK(realfile.length() / 1024);
            bf.setOldName(fileName);
            bf.setExtension(fileextension);
            bf.setNewName(realfilename);
            bf.setOriginPath(basepath + midpath + datepath + "/" + realfilename);

            //如果是图片的话，判断：大小是否合适，宽高是否合适
            //if(ImgUtils.IMAGE_DEFAULT_EXTENSION.indexOf(fileextension) > -1	){
            //    bf.setType("image");
            //    BaseFile bf1 = new BaseFile();
            //    if(ImgUtils.compressImgMaxSize(realfile, maxpicwidth, maxpicheight, bf1)){
            //        bf.setLengthK(bf1.getLengthK()/1024);
            //        bf.setWidth(bf1.getWidth());
            //        bf.setHeight(bf1.getHeight());
            //        bf.setNewName(bf1.getNewName());
            //        bf.setNewPath(bf1.getNewPath());
            //        bf.setOriginPath("/upload"+midpath+datepath+"/"+bf1.getNewName());
            //    }
            //    if(!StringUtils.isNullOrEmpty(maxpicm)){
            //        long maxLength = Long.parseLong(maxpicm);
            //        long oldLength = 1024 * bf.getLengthK();
            //        if(maxLength < oldLength){
            //            float rate = 1.0f * maxLength / oldLength;
            //            BaseFile bf2 = new BaseFile();
            //            if(ImgUtils.compressImgQuality(realfile, rate, bf2)){
            //                bf.setLengthK(bf2.getLengthK()/1024);
            //                bf.setWidth(bf2.getWidth());
            //                bf.setHeight(bf2.getHeight());
            //                bf.setNewName(bf2.getNewName());
            //                bf.setNewPath(bf2.getNewPath());
            //                bf.setOriginPath("/upload"+midpath+datepath+"/"+bf2.getNewName());
            //            }
            //        }
            //    }
            //    if(bf.getWidth() == 0){
            //        Map<String, Integer> wh = ImgUtils.getImageWidthHeight(realfile);
            //        bf.setWidth(wh.get("width"));
            //        bf.setHeight(wh.get("height"));
            //    }
            //}

            String resultpath = MediaBaseUrl + basepath + midpath + datepath + "/" + bf.getNewName();
            bf.setNewPath(resultpath);

            return bf;

        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        }

    }

    /**
     * 从request中获取 midpath，默认为："/file"，格式为：(/[a-z0-9]+)+
     * 如果值为字符串"null" --> ""
     * 如果值为非法字符 --> "/file"
     *
     * @param request
     * @return
     */
    private String getMidpath(HttpServletRequest request) {
        String midpath = "/file";
        String _midpath = request.getParameter("midpath");
        if (!StringUtils.isNullOrEmpty(_midpath)) {
            if ("null".equals(_midpath)) {
                midpath = "";
            } else if (StringCheck.check("^(/[a-z0-9]+)+$", _midpath)) {
                midpath = _midpath;
            }
        }
        log.info("midpath:" + _midpath + " -> " + midpath);
        return midpath;
    }

    /**
     * 从request中获取 datepath，默认为"/yyyy/MM/dd"
     * 如果值为字符串"null" --> ""
     * 如果值为非法字符 --> "/yyyy/MM/dd"
     *
     * @param request
     * @return
     */
    private String getDatepath(HttpServletRequest request) {
        String datepath = DateUtils.getCurFormatDateTime("/yyyy/MM/dd");
        String _datepath = request.getParameter("datepath");
        if (!StringUtils.isNullOrEmpty(_datepath)) {
            if ("null".equals(_datepath)) {
                datepath = "";
            } else if (StringCheck.check("^(/[yMd]+)+$", _datepath)) {
                datepath = DateUtils.getCurFormatDateTime(_datepath);
            }
        }
        log.info("datepath:" + _datepath + " -> " + datepath);
        return datepath;
    }

    /**
     * 从request中获取 maxpicm，无默认值，只能是数字
     *
     * @param request
     * @return
     */
    private String getMaxpicm(HttpServletRequest request) {
        String maxpicm = "";
        String _maxpicm = request.getParameter("maxpicm");
        if (!StringUtils.isNullOrEmpty(_maxpicm)) {
            if (StringCheck.check("^[1-9]\\d*$", _maxpicm)) {
                maxpicm = _maxpicm;
            }
        }
        log.info("maxpicm:" + _maxpicm + " -> " + maxpicm);
        return maxpicm;
    }

    /**
     * 从request中获取 maxpicwidth，无默认值，只能是数字
     *
     * @param request
     * @return
     */
    private String getMaxpicwidth(HttpServletRequest request) {
        String maxpicwidth = "";
        String _maxpicwidth = request.getParameter("maxpicwidth");
        if (!StringUtils.isNullOrEmpty(_maxpicwidth)) {
            if (StringCheck.check("^[1-9]\\d*$", _maxpicwidth)) {
                maxpicwidth = _maxpicwidth;
            }
        }
        log.info("maxpicwidth:" + _maxpicwidth + " -> " + maxpicwidth);
        return maxpicwidth;
    }

    /**
     * 从request中获取 maxpicheight，无默认值，只能是数字
     *
     * @param request
     * @return
     */
    private String getMaxpicheight(HttpServletRequest request) {
        String maxpicheight = "";
        String _maxpicheight = request.getParameter("maxpicheight");
        if (!StringUtils.isNullOrEmpty(_maxpicheight)) {
            if (StringCheck.check("^[1-9]\\d*$", _maxpicheight)) {
                maxpicheight = _maxpicheight;
            }
        }
        log.info("maxpicheight:" + _maxpicheight + " -> " + maxpicheight);
        return maxpicheight;
    }
}
